package com.macro.mall.portal.config.sharding.ranghash;

import cn.hutool.core.util.HashUtil;
import com.macro.mall.common.shard.ShardThreadLocal;
import com.macro.mall.portal.domain.ShardFragmentTable;
import com.macro.mall.portal.domain.ShardNode;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * @author wwj
 */
public class RangHashPreciseTableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {



    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {

        Long id = preciseShardingValue.getValue();
        ShardThreadLocal.put(id);
        ShardNode shardNode = RangeHashAlgorithm.getShardNode(preciseShardingValue.getLogicTableName(), id);
        List<ShardFragmentTable> shardFragmentTables = RangeHashProperties.shardFragmentMap.get(shardNode.getId());

        int tableMod = HashUtil.pjwHash(id + "") % shardNode.getFragmentCount();
        Optional<ShardFragmentTable> shardFragmentTableOptional = shardFragmentTables.stream().filter(s -> s.getHashValue() == tableMod).findFirst();
        if (shardFragmentTableOptional.isPresent()) {
            return shardFragmentTableOptional.get().getName();
        }
        throw new UnsupportedOperationException();
    }
}
